import sys
import inspect
import random

import pygame
from pygame.locals import *

import sprites
import common

screen = pygame.display.set_mode((640,480))
clock = pygame.time.Clock()
SCREENRECT = common.SCREENRECT


class Level(object):

    id = 0

    def __init__(self):
        self.score = 0 

    def run(self):
        player_g = sprites.BaseSpriteGroup()
        blocks_g = sprites.BaseSpriteGroup()
        buffer_blocks_g = sprites.BaseSpriteGroup()
        bullets_g = sprites.BaseSpriteGroup()
        all = sprites.BaseRenderUpdates()

        sprites.Ship.add_groups(player_g, all)
        sprites.Block.add_groups(blocks_g, all)
        sprites.Bullet.add_groups(bullets_g, all)
        sprites.Score.add_groups(all)

        player = sprites.Ship(SCREENRECT.midbottom)
        score = sprites.Score(self)

        background = pygame.Surface(screen.get_size()).convert()
        background.fill((0,0,0))
        screen.blit(background, (0,0))

        while player.alive():
            for event in pygame.event.get():
                if event.type == QUIT or \
                    (event.type == KEYDOWN and event.key == K_ESCAPE):
                        return
            keystate = pygame.key.get_pressed()
            all.clear(screen, background)
            all.update()
            direction = keystate[K_RIGHT] - keystate[K_LEFT]
            player.move(direction)

            firing = keystate[K_SPACE]
            if not player.reloading and firing:
                sprites.Bullet(player.gunpos)
            player.reloading = firing

            if pygame.sprite.groupcollide(bullets_g, blocks_g, 1, 1):
                self.score += 10
            
            # remove blocks that are fully on the screen
            buffer_blocks_g.remove(*[b for b in buffer_blocks_g.sprites() if b.rect.top > SCREENRECT.top])

            #draw new block
            if not int(random.random() * self.BLOCK_ODDS):
                block = self.create_block()
                b_list = pygame.sprite.spritecollide(block, buffer_blocks_g, 0)
                while len(b_list) > 0:
                    block.rect.bottom = min(b.rect.top for b in b_list) - 1
                    b_list = pygame.sprite.spritecollide(block, buffer_blocks_g, 0)
                buffer_blocks_g.add(block)
                
            dirty = all.draw(screen)
            pygame.display.update(dirty)

            clock.tick(60)

        return player.alive()

    def create_block(self):
        pass

    def stop(self):
        pass


class Level1(Level):

    BLOCK_ODDS = 60
    BLOCK_SPEED = 7
    id = 1

    def create_block(self):
        return sprites.Block((random.randint(0, 640), 0), self.BLOCK_SPEED)




_LEVELS = dict([(level.id, level) for name, level in \
                inspect.getmembers(sys.modules[__name__]) if inspect.isclass(level) \
                and issubclass(level, Level)])

NUM_LEVELS = len(_LEVELS) - 1

def load_level(level_id):
    return _LEVELS.get(level_id, Level)()

